# 11111111111111111111111111111111
# 2.1 字符串
# 字符串的定义
# 字符串定义:
# 空:
# 用引号: 字符串变量名=""
# 非空（常用）
# 用引号: 字符串变量名="元素值"

# data="";
# data2="qyh";


# 定义形式:
# 单引号：值上面加单引号
# 双引号：值上面加双引号
# 三引号：值上面加三对引号（注释内容也属于字符串内容）
# 注意事项：
# 特殊字符串：
# 带有转义字符的字符串 ---> 转义字符字符串外面加 r 字符串内信息原样输出
# 单双引号配合的字符串 ---> 单双引号的字符串，可以通过字符串的引号交叉使用【单引号和双引
# 号交叉】

# 字符串的使用
# 字符元素查找
# 格式： 字符串变量名[下标]
# # 定义变量
# info1 = "D:\tools\noco"
# info2 = r"D:\tools\noco"
# info3 = "D:\\tools\\noco"
# info4 = '张三说："你很厉害"'
# print(info1) # 字符串中有转义字符，不能原样输出
# print(type(info2))
# print(info3)
# print(info4)
# # \n 表示换行
# # \t 表示执行TAB
# # 问题1：路径想原样输出,在字符串外面添加字母 r，或者在有转义字符的地方添加 \
# # 问题2：字符串中本身存在单双引号的情况，需要交叉输入引号



# 字符元素查找
# 格式： 字符串变量名[下标]
# 结果：存在，返回元素，不存在下标报错
# 字符位置查找
# 下标：计算机中存放字符/元素的位置，也是计算机计数一种方式，默认从0开始
# 语法格式： 字符串名.find(被查找字符)
# 执行结果：
# 查找成功：返回字符所在下标（索引）
# 查找失败：返回-1

# data="abcdefg";
# # 通过字符下标 查询对应数据
# print(data[3]);
# # 通过字符元素 查询对应数据位置
# print(data.find('d'));

# 字符串替换
# 语法格式： 字符串名.replace(原字符串,新字符串)
# 注意事项：
# 字符串属于不可变数据类型，替换不会修改原有字符串信息
# 字符串替换需要新字符串变量接收查看是否替换成功
# 案例演示
# 字符串连接
# 语法格式： 连接字符.join(列表/元组/集合)
# 注意事项：
# 按照指定字符串将列表/元组中的字符元素（非字符元素报错）连接为字符串
# 案例演示
# 定义字符串
# data="qyh,hhhh";
# name=["aaa","ddd"];
# # 使用字符串（替换）
# data1=data.replace("qyh","hwg")
# print(f"原：{data},旧：{data1}");
#
# # 使用字符串（链接）
# data2="and".join(name); # 为列表，因元素以划分好，所不会拆分，会直接链接
# data3="and".join(data); # 链接的是字符串时 会将字符串拆分为单独的字符，进行链接
# print(f"原：{name},旧：{data2}");
# print(f"原：{data},旧：{data3}");
# # 结论：
# 字符串不可变数据类型，进行替换操作之后，原有的字符串不发生变化


# 字符串拆分🏴
# 应用场景：将字符串按照指定的字符拆分为列表，方便获取指定数据
# 语法格式： 字符串名.split(分割符)
# 注意事项：
# 字符串拆分之后的结果为列表，按照指定分割符分割
# 如果不输入分割符，默认按照字符串中的空格分割
# data="qyh,hhhh";
# daa1=data.split(',');
# print(f"源数据{data}，拆分之后的据类型：{type(daa1)}，结果：{daa1}");

# 案例演示
# 字符串其他操作
# 字符串中字母大小写转换
# 转大写： 字符串.upper()
# 转小写： 字符串.lower()

# data="qyh,hhhh";
# data1=data.upper();
# data2=data.lower();
# print(f"{data1},x{data2}");
# 判断是否是字母/数字【注意：字符串中不能出现空格】
# 判断是字母： 字符串.isalpha()
# 判断是数字： 字符串.isdigit()

# data="qyhjfhhhh";
# daa="128848928292";
# data1=data.isdigit();
# data2=data.isalpha();
# print(f"{data1},{data2}");
# print(daa.isalpha());
# print(daa.isdigit());


# 判断某个字符出现的次数： 字符串.count("字符")
# data=" abcdaabdsss ";
# print(data);
# print(data.count('b'));
# 字符串两头去除空格 strip()
# data1=data.strip();
# print(data1);

# 案例
# 获取数据并去除空格，以及相应数据处理
# dinahua=input("请输入电话:").strip();
# if dinahua != "" and len(dinahua)==11:
#     mima = input("请输入密码:").strip();
#     if mima != "" :
#         yanzma = input("请输入验证码:").strip().lower();
#         if yanzma !="" :
#             if dinahua == 13488888888 :
#                 if mima == 123456:
#                     if yanzma == "8888":
#                         print(f"登录成功账号为‘{dinahua}’");
#                     else :
#                         print(f"验证码与图片内容不符");
#                 else:
#                     print(f"密码与账号不匹配");
#             else:
#                 print(f"手机号不存在");
#         else:
#             print(f"验证码不能为空");
#     else:
#         print(f"密码不能为空");
# else :
#     print("电话格式为十一位数字，且不能为空")





#  22222222222222222222222222222222222222222
# 列表的定义
# 空列表：
# 在实际测试中经常需要定义空列表，存放常用的一些测试数据
# 用[]定义： 列表变量名 = []
# 类实例化方式定义： 列表变量名 = list

# data=[];
# data1=list();


# 非空列表：
# 列表变量名 = [元素1,元素2,...]
# data2=[1,2,3,4,"ffdfdf",'dsds',3]

# 案例演示
# 列表的使用
# 列表元素查询：索引🏴
# 应用场景：查看列表中某个位置的元素，方便获取
# 语法格式： 列表名[索引]
# 注意事项：
# 结果返回的是索引（也叫下标）对应列表元素，索引默认从0开始
# 如果查询的索引不存在，则代码会报错
#print(data2[3]);
# 根据列表中的元素查询其位置（下标） index
# print(data2.index(4));
# 列表元素统计  count()
# data=["java","python","java基础","html","js"];
# print(data.count("java基础"));

#列表元素增加：末尾增加元素 1:  .append(元素) 一次只能添加一次
# data=["java","python","java基础","html","js"];
# print(f"原：{data}");
# data.append("c++");
# print(f"新：{data}");
# data.append("c+");
# print(f"新：{data}");

# 列表元素增加：指定位置增加元素 2： .insert(位置，元素); 位置（下标）存在 就将原数据往后排，自己顶替 ，不存在就默认最后
# data=["java","python","java基础","html","js"];
# data.insert(4,"qyh");
# print(data);
# data.insert(6,"qyh");
# print(data);

# 列表合并 .extend(列表名2) 谁发起的操作，最终数据就在它哪里
# data=["java基础","html","js"];
# data2=["java","python"];
# data3=data.extend(data2);
# print(data);
# print(data2);
# print(data3);

# 列表元素删除：指定索引位置删除 .pop(索引); 索引不写则删除最后一个，无效或超出则错误提示
# data=["java基础","html","js"];
# data.pop(1);
# print(data);
# data.pop();
# print(data);

# 列表元素删除：指定数据删除  .remove(元素) 要准确完整的元素内容
# data=["java基础","html","js"];
# data.remove("java基础");
# print(data);

# 列表元素修改：修改指定索引的数据 列表名[索引]=新数据   如何该位置有数据则会被替换, 如果列表中没有该索引则会报错
# data=["java基础","html","js"];
# data[2]="qyh"
# # data[4]="qyh"
# print(data);

# 列表元素反转：元素倒置（反转） 列表名.reverse()；
# data=["java基础","html","js"];
# data.reverse();
# print(data);

# 列表元素排序：大小排列 列表名.sort(reverse=False) 为True  大到小  False 小到大
# data=["java基础","html","js"];
# data.sort(reverse=True);
# print(data);
# data.sort(reverse=False);
# print(data);


# #列表嵌套
# student_list = [["张三", "18", "功能测试"], ["李四", "20", "自动化测试"], ["王五", "22",
# ["python", "java"]]]
# #获取指定的元素
# # 查找元素18，如何查找'
# print(student_list[0][1]);
# #合并
# data3=student_list[2];
# student_list[0].extend(data3);
# print(student_list);


# 33333333333333333333333333333333333333333333333
# 2.3 元组
# 元组的定义
# 空元组：
# 用()定义： 元组变量名 = ()
# 类实例化方式定义： 元组变量名 = tuple()

# data=();
# data1=tuple()
# print(type(data));
# print(type(data1));


# 非空元组：
# 元组变量名 = (元素1,元素2,...)
# 元组变量名 = 元素1,元素2,...
# 注意事项
# 元组的元素有多个时，小括号可以不写
# 元组只有一个元素时，写小括号，且元素后面加逗号： (元素,) 不加其值为int型
# data=(1,);
# data1=(1,3,4,1,2);
#
# print(type(data));
# print(data);
# print(type(data1));
# print(data1);
# 案例演示
# 元组的使用
# 元组元素查询：索引
# 语法格式： 元组名[索引]
# 注意事项：
# 结果返回的元组元素的索引（也叫下标），默认从0开始
# 如果查询的索引不存在，则代码会报错
# 案例演示
# data=(1,);
# data1=(1,3,4,1,2);
# print(type(data));
# print(data1[3]);
# print(type(data1));
# print(data1);


# 元组元素查询：元素统计 .count();
# data1=(1,3,4,1,2);
# print(data1.count(3));

# 元组其他应用：数据交换
# 传统方式：通过第三方的空杯子DATA1空掉，然后注入data2，在由data2,接受第三方num存储的data1 完成替换
# data1=(1,3,4,1,2);
# data2=(1,3);
# num=();
# num=data1;
# data1=data2;
# data2=num;
# print(data1);
# print(data2);
# print(num);

# 替换方式 2：直接借助于python元组类型的数据直接替换
# # aa = 200 # 相当于把200给aa
# # bb = 100 # 相当于把100给bb
# # num1 = aa
# # num2 = bb
# # 合并结果 # num1, num2 = 200, 100
# num1, num2 = num2, num1 # 元组元素的外层小括号可以省略
# print("此时num1的值：", num1)
# print("此时num2的值：", num2)

# 个人理解：将元组进行二次存储（不直接使用初始元组变量，而是使用副本进行操作）通过b 等号 将两副本变量进行 ’正反比对赋值‘
# 完成 替换
# # 初始元组
# data1=(1,3,4,1,2);
# data2=(1,3);
# # 建立元组副本
# num1=data1;
# num2=data2;
# print(f"替换之前的num1:{num1},替换之前的num2：{num2}")
# # 通过 等号 将副本变量 正反比对赋值，左为正，右为反
# num1,num2=num2,num1;
# print(f"替换之后的num1:{num1},替换之后的num2：{num2}")





# 444444444444444444444444444444444444

# 字典
# 字典的定义
# 空字典：
# 用{}定义： 字典变量名 = {}
# 类实例化方式定义： 字典变量名 = dict()
# data={};
# data1=dict();

# 非空字典【常见】：
# 字典变量名 = {键1:值1,键2:值2,...}
# 注意事项
# 字典中的键一般使用字符串，其中键名不能重复（重复了数据会被覆盖）
# 字典中的数据俗称“键值对”

# data={"name":"张三","age":17};
# print(f"类型：{type(data)}\n打印结果：{data}");

# 字典新增或修改值：字典名[键]=值  字典中键存在则修改值，键不存在则新增值
# 对谁操作，其最后数据就在谁那里 不需要建立新的变量进行重复存储
# （列表、字典、集合是可变的，其余都不可变，所以会需要创建新变量存储修改之后的结果）
# data={"name":"张三","age":17};
# print(f"原类型：{type(data)}\n打印结果：{data}");
# data['name']='李四';
# data['age']=22;
# print(f"修改之后类型：{type(data)}\n打印结果：{data}");
# data['sex']='男';
# print(f"新增之后类型：{type(data)}\n打印结果：{data}");

# 字典删除：字典名.pop(键)  pop的键不能为空
# data={"name":"张三","age":17};
# print(f"原类型：{type(data)}\n打印结果：{data}");
# data.pop("age");
# print(f"删除之后类型：{type(data)}\n打印结果：{data}");

# 字典中取值 1、变量 = 字典名[键] 2、变量 = 字典名.get(键)
# 区别在于两者返回的结果不一样，方式1键不存在则直接报错，2会返回None 意思为空
# data={"name":"张三","age":17};
# # data2=data["sex"];
# # print(data2)
# data3=data.get("sex");
# print(data3)

# 案例：实验4 综合案例1
# info = {
# "name": "tom",
# "age": 18,
# "gender": "男",
# "hobby": {"read": "小说", "sport": ["篮球", "足球"]}
# }
# 查询年龄
# print(f"info中年龄：{info.get('age')}");
# 查询键aa的值
# print(f"info中aa：{info.get('aa')}");
# 思考：如何获取值："足球
# 由于足球位于sport 键中且s为hobby键的取值，所以要先获取hobby，在对其hobby进行get操作
# h 变量现存储的是 一个字典数据序列 所以其类型也为 字典
# h=info.get('hobby');
# print(f"将hobby存储于h变量中，其类型为：{type(h)},先查看其h数据{h}");
# 开始对H进行get操作获取其想要的sport数据（足球的键为sport）
# 由于sport键取值为一个列表数据序列，所以可在其sport数据之后通过下标完成足球的获取
# print(f"h.get('sport')结果为:{h.get('sport')[1]}"); #


# 字典的合并/新增 字典2.update(字典1)
# data={"name":"颤三","sex":"男"};
# data2={"age":166};
# # 将data2融入data
# data.update(data2);
# print(f"类型：{type(data)},合并结果：{data}")


# 字典的遍历
# 方式1 for 临时变量 in 字典名.keys():取出字典中的 ’所有键‘，容器后面可以不写 .keys()
# 注意 在Python 中for 常用于数据遍历 所以 临时变量 的循环参数是跟 数据源 挂钩的
# 所以不能另作 计数器 使用  须在循环之外构建 计时器变量 默认为1 之后 通过其自增（计数器变量每次循环加一）
# 由因 计数器为循环完成之后 最后执行的代码 所以计数器需要再次减一   因为它最后一次之前 for就已经完成了 不需再加1
# 完成计数效果
# num=1;
# data={"name":"颤三","sex":"男","age":17,"hhhh":"ddsdsdsds"};
#
# for i in data:
#     print(f"数据：{i}")
#     # print(f"循环参数为：{num}")
#     num += 1;
# print(f"循环参数为：{num-1}")

# 方式2 遍历字典值 for 临时变量 in 字典名.values() 取出字典中的’所有值‘
# num=1;
# data={"name":"颤三","sex":"男","age":17,"hhhh":"ddsdsdsds"};
#
# for i in data.values():
#     print(f"数据：{i}")
#     # print(f"循环参数为：{num}")
#     num += 1;
# print(f"循环参数为：{num-1}")

# 方式3  遍历字典键和值 for 键变量,值变量 in 字典名.items():  取出字典中的 ’所有键和值‘
# num=1;
# data={"name":"颤三","sex":"男","age":17,"hhhh":"ddsdsdsds"};
#
# for i in data.items():
#     print(f"数据：{i}")
#     # print(f"循环参数为：{num}")
#     num += 1;
# print(f"循环参数为：{num-1}")


# 55555555555555555555555555555555555555555555555555555555

# 集合 用来描述不重复的可变类型的数据集。常常用来去重，集合是无序的
# 空集合：
# 类实例化方式定义： 变量名 = set()
# data=set();
# # 非空集合：
# # 集合变量名 = {值1,值2,...}
# data2={1,3,4,'ffe'}
#
# print(f"类实例化方式定义集合 类型：{type(data)}")
# print(f"非空集合 类型：{type(data2)}, 值为：{data2}")

# 集合元素添加 集合.add(元素)
# data2={1,3,4,'ffe'}
# data2.add(1232);
# print(f"类型：{type(data2)}, 添加元素后值为：{data2}");

# 列表元素去重 变量 = set(列表名)
# data2={1,3,4,'ffe',2,1,5,1,2,3,4,2,1}
# data=set(data2);
# print(f"类型：{type(data)}, 去重复值为：{data}");
# dat=list(data);
# print(f"类型：{type(data)}, 强转为列表 值为：{dat}");

# 可通过将数据转为不同数据序列（列表、元组、集合）完成对数据的处理



# 666666666666666666666666666666666666666666666666666666666666666666666
# 序列类型-通用操作
# 切片操作 取出序列中一部分（一段）数据【数据类型不变】，以字符串、列表、元组为主
# 变量名[start:end:step]   下标 顾头不顾尾   开始和结束不写则默认 从第一开始到结束
# start：切片开始下标
# end：切片结束下标
# step：切片步长【可选】
# 正向索引：步长为正数，从左向右 012345          (数据：{1，2，3，4，5，7})
# 负向索引：步长为负数，从右向左 -6-5-4-3-2-1

# 案例
# 作用：按照指定要求获取一段数据
# 定义非空字符串
# name = "abcdefgh"
# # 获取cde
# print(name[2:5])
# # 获取defgh的字符
# print(name[3:])
# # 获取abc的字符
# print(name[:3])
# # 获取ace的字符
# print(name[0:5:2])
#
# #序列长度 len(变量名)  作用：计算序列的长度（统计元素的个数）常常应用于对后台返回数据进行统计某个对象数据的长度
# print(len(name));

# 清空序列 空序列中所有数据，以列表和字典为主（支持可变数据类型清空）
# 变量名.clear()

# data=[1,2,3,4,5,6,6,7,8,99,0,0];
# data1= {"nanme":"ffdfdfdf","ds":33};
# print(data.clear());
# print(data1.clear());





# 综合案例 1
# 需求：
# 参考项目的登录功能（登录时需要输入用户名、密码、验证码），至少设计3条测试用例
# 要求1：定义变量保存测试数据（包括不同测试数据对应的测试结果）
# 要求2：至少写出3种以上不同的数据格式
# 要求3：遍历测试数据并打印到控制台，数据格式“用户名：xxx 密码：xxx 验证码：xxx 期望结果：xxx


# 准备数据
# login_data1 = [
# ["13800000001", "123456", "8888", "登录成功"],
# ["13800000001", "1234", "8888", "密码错误"],
# ["13800000001", "123456", "0000", "验证码错误"]
# ]
# # 定义变量：元组
# login_data2 = (
# ("13800000001", "123456", "8888", "登录成功"),
# ("13800000001", "1234", "8888", "密码错误"),
# ("13800000001", "123456", "0000", "验证码错误")
# )
# # 定义变量：列表元组
# login_data3 = [
# ("13800000001", "123456", "8888", "登录成功"),
# ("13800000001", "1234", "8888", "密码错误"),
# ("13800000001", "123456", "0000", "验证码错误")
# ]
# # 定义变量：列表字典
# login_data4 = [
# {"username": "13800000001", "password": "123456", "code": "8888", "result": "登录成功"},
# {"username": "13800000001", "password": "666666", "code": "8888", "result": "密码错误"},
# {"username": "13800000001", "password": "123456", "code": "0000", "result": "验证码错误"}
# ]
#
#
# # # 遍历数据1
# # 数据格式“用户名：xxx 密码：xxx 验证码：xxx 期望结果：xxx
# print("login_data1")
# for i in login_data1:
#     print(f"用户名：{i[0]} 密码：{i[1]} 验证码：{i[2]} 期望结果：{i[3]}");
# print()
#
# # # 遍历数据2
# # 数据格式“用户名：xxx 密码：xxx 验证码：xxx 期望结果：xxx
# print("login_data2")
# for i in login_data2:
#     print(f"用户名：{i[0]} 密码：{i[1]} 验证码：{i[2]} 期望结果：{i[3]}");
# print()
#
#
# # # 遍历数据3
# # 数据格式“用户名：xxx 密码：xxx 验证码：xxx 期望结果：xxx
# print("login_data3")
# for i in login_data3:  # 每循环一次就将login_data3 存储的数据 赋值给 临时变量I
#     print(f"用户名：{i[0]} 密码：{i[1]} 验证码：{i[2]} 期望结果：{i[3]}");  # 通过元组下标的形式 获取其值
# print()
# print("login_data4")
#
# # # 遍历数据4
# for i in login_data4:  # 每循环一次就将login_data4 存储的数据 赋值给 临时变量I
#     # print(f"用户名：{i.get('username')} 密码：{i.get('password')} 验证码：{i.get('code')} 期望结果：{i.get('result')}");
#     # 使用 f"" 要注意单引号于双引号 交叉引用 在字典中可以使用 字典名['键'] 也可以通过 get方法 两者返回的结果不一样而已
#     print(f"用户名：{i['username']} 密码：{i['password']}  验证码：{i['code']}  期望结果：{i['result']} ");


# 综合案例 2
# 需求：
# # 有两个参数：手机号和密码
# # 手机号的测试数据有三个，密码的测试数据也有三个
# # 最后组装成元组列表类型的数据作为最终的测试数据: [(手机号1,密码1),(手机号2,密码2),...]
# # 总共需要几种场景的测试数据
#
# # 准备数据
# data =[];
# phone_list = ['13880001111', '13999992222', '150999933331']
# password_list = ['123456', '456def', 'aaaaaa']
# # 实现思路：在获取到电话时 同时获取密码 在将其存储为元组形式 ，在存储进列表中
# # 最终达到 列表元组 的数据序列
# for i in phone_list:
#     # print("电话"+i)
#     for j in password_list:
#         # print("密码"+j)
#         data1=(i,j); # 组合为元组
#         data.append(data1);  # 组合之后将其添加如列表中
#
# print(f"数据类型：{type(data)},最终结果：{data}");
#
# # 查看最终组合的列表元组 ，得到符合格式的数据下标
# # 以计数器-1 得到当前的下标（for 循环的次数是根据内容的 所以每循环一次 计数器加一时就得到了数据个数 在减一时就得到了其下标）
# # 通过与符合格式下标进行比对 符合则加入到新的列表中 就达到了 想要的数据个格式 [(手机号1,密码1),(手机号2,密码2),...]
# # 0 4 8
# num =1;
# data2=[];
# for i in data:
#     if (num-1) in (0,4,8):
#         data2.append(i)
#     num+=1;
#
# print(f"数据类型：{type(data2)},最终结果：{data2}");


# 综合案例 3  包与模块、判言的使用 api scripts文件中


# 变量与数据
# # # 定义变量：不可变数据类型
# data=321;
# # num = 100
# # # 查看变量的引用（数据在内存的中地址）
# print(f"原数据：{data},数据在内存中的地址为：{id(data)}");

# print(id(num)) # 1396671927760
# # 重新赋值（不可变类型需要重新开辟空间）
# num = 200
# data=432;
# print(f"原数据：{data},数据在内存中的地址为：{id(data)}");
# # print(id(num)) # 1396671931024
# # # 结论:给变量赋值本质修改的是数据的引用
# # # 即:重新赋值后内存地址是不一样的
# # # 定义变量：可变类型
# list1 = [1,2,3]
# print(f"原数据：{list1},类型：{type(list1)}数据在内存中的地址为：{id(list1)}");
# # print(id(list1)) # 1396677525696
# # # 查看数据/变量的引用
# list1.append(4)
# print(f"原数据：{list1},类型：{type(list1)}数据在内存中的地址为：{id(list1)}");
# # print(id(list1)) # 1396677525696

# 局部变量 作用域：函数内部定义变量,只能在函数内部使用（方法也是一样） 局部局部就是在限定的而某一处使用
# 全局变量 作用域：函数外部定义的变量,(当前模块)所有函数内部都可以使用（方法也是一样）  全局即在整个所属模块文件（程序文档）中创建，即可在此文档任意调用
# 有局部优先使用局部变量，没有再使用全局变量
# 案例
# 作用域：了解使用变量时的作用范围
# def add_test(num1, num2):
#     # 局部变量
#     num1 = 100
#     print(num1 + num2)
# def sub_test(num1, num2):
#     print(num1-num2);
#
# add_test(10,200) # 300
# sub_test(10,200)

# 函数进阶
# 缺省参数 应用: 定义函数时,给函数的参数一个默认值
# 定义函数时,存在多个参数,并且有缺省参数时,将缺省参数置于参数列表的末尾 ：def stu_info(name, age, gender="男") 缺省值 gender="男"
# 调用函数时,如果没有传入缺省参数值,则使用默认值;如果传入参数值了,则使用传入的值
# 调用函数时,如果有多个缺省参数,需要指定缺省参数名和值的对应关系【一一对应】
# stu_info("李四", 19, "女")， def stu_info(name, age, gender="男")  两者参数一一对应
# 实参与形参也是要一一对应的 不然调用的时候数值相反


# 多值参数
# > 应用场景: 定义函数处理的参数个数不确定,需要用多值参数
# 案例
# 需求:
# 1. 定义一个函数 sum_numbers，可以接收的 任意多个整数
# 2. 功能要求：将传递的 所有数字累加 并且返回累加结果
# 分析：
# 1.定义函数（有参数，并且个数不确定）
# def sum_numbers(*args):
# # 一个变量args接收了一堆数据（元组类型数据）如：args = (1,2,3,4,5)
#     # 定义初始结果变量
#     result = 0
#     # 先取出元素
#     for i in args:
#         # 在累加求和
#         result += i
#         # 返回结果
#     return f"累加的结果是：{result}"
# # 2.调用函数
# aa = sum_numbers(1,2,3,4,5,6)
# print(aa)

# 元组拆包  调用函数时，在元组变量名前加 *
# （其实是在函数的形参添加 意为 当实际参数传到此函数时 先拆分数据然后使用 格式就是在 多值参数前 加* 号）
# 总的来说对于 多值参数 在函数调用数据时要先进行拆包操作（加* 号） 然后进行正常使用 ；多值参数 一般为列表、元组、集合、字典的数据序列


# 匿名函数
# 应用场景 1.简化带有‘形参和返回值的函数定义’ 2.某些方法（函数）需要传递一个函数作为参数时可以使用匿名函数，传入到其他方法（函数）里
# 使用前提：相当于普通函数有参数，普通函数有返回值场景，可以用匿名函数
# 编写要求：
#   没有名字的函数,即不需要关键字def去定义,但是需要**lambda**关键字说明
# ‐ 匿名函数可以接收**任何数量**的参数,但是只**返回**一个表达式的值
# 具体格式如下：变量名 = lambda 参数1,参数2,... : 表达式
# 表达式即对数据（参数）的处理 从而达到想要的效果
# 如 Max=lambda num,num3:num>num3  # print(max(2,21)) 按照表达式他会返回最大的数31  此表达式为 > 符号
# 案例说明
# 1.普通函数实现两个数字求和
# 定义函数
# def demo(a, b):
#     result = a + b
#     # 返回结果
#     return result
#     # 调用函数
# print(demo(10, 20))
#
# # 2.匿名函数实现两个数字求和
# result = lambda a, b: a + b
# # 使用匿名函数
# print(result(10, 20))

# def get_Max(num1=20,num2=30):
#     if num1>num2:
#         print(f"最大为：{num1}")
#     else:
#         print(f"最大为：{num2}")
#
# get_Max();
#
# Max=lambda num,num3:num>num3
# print(max(2,21))



# 异常
# 预防代码执行过程中出现错误时中断，可以通过捕获异常的方式自定义出现异常之后执行的操作
# 在代码调试中，想知道具体的异常信息，可以通过异常捕获去实现
# 代码程序运行出现的错误，就是异常，提示错误信息的过程叫抛出异常（raise）
# 处理出现的异常叫捕获异常 ---> 让代码能自动执行下去
# 注意事项
# except 后面每次只能跟一种类型错误
# 上述语法关键词必须对齐
# 上述关键词后面都需要加冒号

try:
# # 尝试执行的代码
    num=int(input("亲输入数字："));
    print(num)
# pass
except Exception as e:
    print(f"错误信息：{e}")
# # 针对错误类型1， 对应的代码处理
except ValueError:
    print("不能输入非数字")
# except Exception as e:
# # 打印错误信息
# print(e)
else:
# # 没有异常才会执行的代码
    if num % 2 == 0:
        print(f"{num}为偶数")
    else:
        print(f"{num}为奇数")
finally:
# # 无论是否有异常， 都会执行的代码
    print("SP")
# pass


# 模块调用源代码
# # 构建 登录功能 函数   api文件西安
# def login(dianhua):
#     if dianhua == "13488888888":
#         return("账户成功")  # 符合则返回 账户成功 信息
#     else:
#         return("账号错误")